
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>秒杀系统设计 - 学习卡片</title>
      <style>
        body { font-family: sans-serif; background-color: #f0f8ff; color: #333; display: flex; flex-direction: column; align-items: center; padding: 50px 20px; }
        .header h1 { font-size: 32px; }
        .grid-container { display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; width: 100%; max-width: 1200px; }
        .card-container { perspective: 1200px; cursor: pointer; height: 250px; }
        .card { width: 100%; height: 100%; position: relative; transform-style: preserve-3d; transition: transform 0.7s; border-radius: 16px; box-shadow: 0 4px 16px rgba(0,0,0,0.08); }
        .card-container.flipped .card { transform: rotateY(180deg); }
        .card-face { position: absolute; width: 100%; height: 100%; backface-visibility: hidden; display: flex; flex-direction: column; box-sizing: border-box; border-radius: 16px; background-color: #fff; padding: 24px; }
        .card-back { background-color: #f0fff4; transform: rotateY(180deg); justify-content: space-between; }
        .card-category { font-size: 14px; color: #0052d9; margin-bottom: 8px; font-weight: 500; }
        .card-question { font-size: 20px; font-weight: 500; flex-grow: 1; display: flex; align-items: center; justify-content: center; text-align: center; }
        .card-answer-wrapper { flex-grow: 1; overflow-y: auto; }
        .card-answer { font-size: 15px; line-height: 1.7; }
        .card-footer { font-size: 13px; color: #8a919f; border-top: 1px solid #f0f0f0; padding-top: 16px; margin-top: 16px; }
        .card-source { font-size: 13px; color: #8a919f; border-top: 1px solid #f0f0f0; padding-top: 12px; margin-top: 12px; }
      </style>
    </head>
    <body>
      <div class="header">
        <h1>秒杀系统设计 - 学习卡片</h1>
      </div>
      <div class="grid-container">
        
    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">理论</div>
          <div class="card-question">从架构视角来看，秒杀系统被定义为什么样的系统？它的“三高”特性指什么？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">理论</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">从架构视角来看，秒杀系统本质是一个高性能、高一致、高可用的三高系统。在文档结尾的小结中，也强调了秒杀系统是高并发、高性能和高可用的分布式系统。</div>
          </div>
          <div class="card-source">来源: 秒杀系统介绍 / 秒杀系统设计小结</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">特性</div>
          <div class="card-question">秒杀活动具有哪些不同于普通电商业务的显著特点？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">特性</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">秒杀活动的主要特点包括：高并发（时间极短、瞬间用户量大）、库存量少、业务流程简单（如下订单、扣库存、支付）、存在大量恶意请求、商品通常不经过购物车环节以及系统需要独立部署。</div>
          </div>
          <div class="card-source">来源: 秒杀系统特点</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">理念</div>
          <div class="card-question">秒杀系统设计中，为了应对瞬时大量用户涌入，“削峰”的设计理念是如何定义的？常用的实现技术有哪些？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">理念</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">“削峰”是指在抢购开始时，对于瞬时涌入的大量用户请求进行处理，以避免系统因瞬时峰值过高而崩溃。实现削峰的常用方法有利用缓存或消息中间件（MQ）等技术，异步处理也是削峰的一种实现方式。</div>
          </div>
          <div class="card-source">来源: 秒杀系统设计理念</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">文档中是如何利用乐观锁来防止商品超卖问题的？请描述其SQL实现的关键。</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">通过在商品表 `t_goods` 中增加一个 `version` 字段来实现乐观锁。更新库存时，SQL语句会同时检查商品ID和版本号 (`where id = ? and version = ?`)，只有在版本号匹配时才执行库存扣减，并同时将版本号加一 (`set gstock = gstock - 1, version=version+1`)。这能有效防止并发场景下的超卖问题。</div>
          </div>
          <div class="card-source">来源: 使用乐观锁解决超卖问题</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">什么是接口限流？文档中提到了哪两种核心的限流算法？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">接口限流是指在某一时间窗口内对请求数进行限制，以保持系统的可用性和稳定性，防止因流量暴增而导致系统运行缓慢或宕机。文档中提到的两种常用限流算法是“令牌桶”算法和“漏桶（漏斗算法）”。</div>
          </div>
          <div class="card-source">来源: 接口限流 / 如何解决接口限流</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">请简述“漏斗算法”的工作原理及其在处理突发流量时的特点。</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">漏斗算法将请求比作水，所有请求先进入一个固定容量的漏斗，并以限定的速率从出口流出（被处理）。当请求流入过快时，会在漏斗中积压；如果漏斗已满，后续的请求将被直接拒绝（溢出）。其特点是以固定的速率处理请求，无法应对突发流量。</div>
          </div>
          <div class="card-source">来源: 漏斗算法</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">“令牌桶”算法是如何工作的？相比漏斗算法，它在应对突发流量方面有何优势？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">令牌桶算法以恒定的速率往一个固定容量的桶里放入令牌。处理请求前必须先获取令牌。如果令牌被消耗的速度小于产生的速度，令牌会累积起来。其优势在于，面对瞬时大流量时，系统可以在短时间内消耗累积的令牌来处理这些突发请求，提供了更好的弹性。</div>
          </div>
          <div class="card-source">来源: 令牌桶</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">文档中是如何利用Redis实现“限时抢购”功能的？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">利用Redis的超时（过期）机制。在秒杀活动开始时，将一个代表活动的键（如 seckill_{gid}）存入Redis并为其设置一个等于活动持续时间的超时时间。在处理抢购请求时，首先检查该键是否存在于Redis中，如果键已因超时而消失，则说明秒杀活动已经结束。</div>
          </div>
          <div class="card-source">来源: 限时抢购</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">如何使用Redis来限制单个用户在特定时间内的抢购频率？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">通过为每个用户和商品的组合创建一个唯一的Redis键（如 seckill_{uid}_{gid}），并设置一个较短的过期时间（如60秒）。利用 `setIfAbsent` 和 `increment` 命令，可以记录用户在规定时间内的访问次数。当访问次数超过预设阈值（如10次）时，系统便可以拒绝该用户的后续请求。</div>
          </div>
          <div class="card-source">来源: 限制单用户抢购频率</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">架构</div>
          <div class="card-question">在秒杀系统的整体解决方案中，Nginx和消息队列（MQ）分别扮演了什么关键角色？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">架构</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">Nginx负责：校验恶意请求、负载均衡、动静分离（不走Tomcat获取静态资源）和Gzip压缩。MQ主要用于：削峰限流，通过将订单请求堆积在队列中，让后端的订单处理服务根据自身消费能力来处理，从而保护下游系统。</div>
          </div>
          <div class="card-source">来源: 秒杀系统其它环节解决方案</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">理论</div>
          <div class="card-question">秒杀系统的设计原则是什么？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">理论</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">秒杀系统的设计原则是：“前台请求尽量少，后台数据尽量少，调用链路尽量短，尽量不要有单点”。</div>
          </div>
          <div class="card-source">来源: 秒杀系统设计小结</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">什么是CDN？它在秒杀系统中起到了什么作用？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">CDN（Content Delivery Network，内容分发网络）是布放在用户访问相对集中地区或网络中的缓存服务器。在秒杀系统中，它可以将用户的访问指向距离最近的缓存服务器，用于页面资源的静态化，将访问拦截在离用户更近的层，过滤无效请求，减轻后端服务器压力。</div>
          </div>
          <div class="card-source">来源: 什么是CDN? / 秒杀系统设计小结</div>
        </div>
      </div>
    </div>

      </div>
    </body>
    </html>
